﻿// CScan.cpp: 实现文件
//

#include "pch.h"
#include "ShenTuAi.h"
#include "afxdialogex.h"
#include "CScanUi.h"
#include "../ShenTuApp/STInfo.h"

// CScan 对话框

IMPLEMENT_DYNAMIC(CScanUi, CDialogEx)

HTREEITEM CScanUi::FindData(HTREEITEM htvi, LPARAM lParam)
{
	static TVITEM tvi;
	static HTREEITEM htvires;

	tvi.hItem = htvi;
	tvi.mask = TVIF_PARAM | TVIF_CHILDREN;
	m_tree1.GetItem(&tvi);

	if (tvi.lParam == lParam) return htvi;

	if (tvi.cChildren) {
		htvires = FindData(m_tree1.GetChildItem(htvi), lParam);
		if (htvires) return htvires;
	}

	while (htvi = m_tree1.GetNextItem(htvi, TVGN_NEXT)) {
		htvires = FindData(htvi, lParam);
		if (htvires) return htvires;
	}

	return NULL;
}

CScanUi::CScanUi(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG2, pParent)
{

}

CScanUi::~CScanUi()
{
}

BOOL CScanUi::OnInitDialog()
{
	UpdateData(); //自定义UI里面的绑定控件需要调这个才会自动实例化
	//DWORD dwStyles = GetWindowLong(m_uitree.m_hWnd, GWL_STYLE);//获取树控制原风格
	HICON m_hicn1 = AfxGetApp()->LoadIcon(IDI_ICON1);
	m_mouse_btn.SetIcon(m_hicn1);
	//dwStyles |= TVS_EDITLABELS | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
	m_gameWnd = NULL;
	//SetWindowLong(m_uitree.m_hWnd, GWL_STYLE, dwStyles);//设置风格
	InitSTInfo(m_gameWnd);
	m_gameWnd = CWndManager::Get()->GetGameWnd();
	CRect rs;
	GetClientRect(&rs);
	rs.top  = 0;
	rs.bottom -= 100;
	rs.left = 0;
	rs.right -= 200;
	//m_tree1.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS, rs,this, IDC_TREE1);
	//m_tree1.ShowWindow(SW_SHOW);
	

	return true;
}

void CScanUi::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON1, m_mouse_btn);
	DDX_Control(pDX, IDC_TREE1, m_tree1);
	DDX_Control(pDX, IDC_EDIT1, m_uiname_edit);
	DDX_Control(pDX, IDC_EDIT2, m_parentName_edit);
	DDX_Control(pDX, IDC_EDIT3, m_pos_edit);
}


BEGIN_MESSAGE_MAP(CScanUi, CDialogEx)
	ON_BN_CLICKED(IDOK, &CScanUi::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CScanUi::OnBnClickedCancel)
	ON_WM_MOVE()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_NOTIFY(NM_DBLCLK, IDC_TREE1, &CScanUi::OnNMDblclkTree1)
END_MESSAGE_MAP()


// CScanUi 消息处理程序


void CScanUi::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
	m_tree1.DeleteAllItems();
	m_treedata.clear();
	auto uiroot = CRDWnd2DManager::Get()->GetUIManager_DeskTop();
	if (!uiroot)
	{
		return;
	}
	CRDWnd2DManager::Get()->ShowAllUi(0 ,{0,0},"", uiroot, [&](DWORD parent,const  char* pname, DWORD address, char* name, POINT pos, POINT rePos, SIZE s) {
		//m_tree1.InsertItem();
		char buf[MAX_PATH] = "";
		sprintf_s(buf,"%X__\"%s\"  [%d,%d] re_[%d,%d]   size=[%d,%d]",address,name,pos.x,pos.y,rePos.x,rePos.y,s.cx,s.cy);
		OutputDebugStringA(buf);
		MyTreeData data;
		data.name = string2wstring(name);
		data.str = string2wstring(buf);
		data.parent = parent;
		data.uiaddress = address;
		data.pos = rePos;
		data.s = s;
		//添加到ROOT
		HTREEITEM zcur;//树控制项目句柄

		TV_INSERTSTRUCT TCItem;//插入数据项数据结构


		TCItem.hInsertAfter = TVI_LAST;//在最后项之后
		TCItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVE_EXPAND;//设屏蔽
		TCItem.item.pszText = (LPWSTR)data.str.c_str();
		TCItem.item.lParam = address;//序号
		TCItem.item.iSelectedImage = 1;//选中时图标
		HTREEITEM parentitem = NULL;
		for (auto item : m_treedata) {
			if (item.uiaddress == parent)
			{
				parentitem = item.treeItem;
			}
		}
		//FindData(m_tree1.GetRootItem(), parent);
		if (!parentitem)
		{
			TCItem.hParent = TVI_ROOT;//增加根项
		}
		else
		{
		
			TCItem.hParent = parentitem;//增加根项
		}
		zcur = m_tree1.InsertItem(&TCItem);
		data.treeItem = zcur;
		m_treedata.push_back(data);

	});
//	CPaintDC dc(this); // 用于绘制的设备上下文
//
//// TODO: 在此处添加消息处理程序代码
//
//// 不要为绘制消息而调用 CWnd::OnPaint()
//	CDC* pDC = GetDC();

	//展开ROOT
	m_tree1.Expand(m_treedata[0].treeItem, TVE_EXPAND);
}
void showRectInDesktop(RECT& rect)
{
	// 获得DC
	HDC hDC = ::GetDC(0);
	// 创建实线，宽度为1，红色的笔
	HPEN hPen = ::CreatePen(PS_SOLID, 4, RGB(255, 0, 0));
	// 将笔选入DC
	HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
	// 创建一个透明画刷
	HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
	// 将画刷选入DC
	HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush);
	// 绘制矩形
	::Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
	// 恢复绘图对象
	::SelectObject(hDC, hOldPen);
	::SelectObject(hDC, hOldBrush);
	// 删除绘图对象
	::DeleteObject(hPen);
	::DeleteObject(hBrush);
	// 释放DC
	::ReleaseDC(0, hDC);
}
#include <functional>
void CScanUi::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnCancel();
	RECT re = { 0, 0, 0, 0 };
	RECT re2 = { 0, 0, 0, 0 };
	::GetWindowRect(m_gameWnd,&re);

	::GetClientRect(m_gameWnd, &re2);
	re.top = re.bottom - re2.bottom;
	re.left = re.right - re2.right;
	//DeleteObject(hPen2);

	//EndPaint(hWnd, &ps);
	HTREEITEM parentitem = NULL;
	auto select = m_tree1.GetSelectedItem();
	for (auto item : m_treedata) {
		if (select == item.treeItem)
		{
			
			if (item.parent != 0)
			{
				auto parent = item.parent;
				while (parent)
				{
					//找到此节点的父，父，父
					for (auto ii : m_treedata) {
						if (ii.uiaddress == parent)
						{
							re.left += ii.pos.x;
							re.top += ii.pos.y;
							parent = ii.parent;
							break;
						}
						
						if (parent == 0)
						{
							break;
						}
					}
				}
			}
			re.left =  item.pos.x  + re.left;
			re.top = item.pos.y + re.top;
			re.right = re.left + item.s.cx;
			re.bottom = re.top + item.s.cy;

			//::MessageBoxW(0,item.str.c_str(),0,0);
			break;
		} 
	}
	//re = { 0,0,200,200 };
	showRectInDesktop(re);
}


void CScanUi::OnMove(int x, int y)
{
	CDialogEx::OnMove(x, y);

	// TODO: 在此处添加消息处理程序代码
}


void CScanUi::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnMouseMove(nFlags, point);
	std::string buf = std::to_string(point.x) + "," + std::to_string(point.y) + "\n";
	//OutputDebugStringA(buf.c_str());
	//获取鼠标所在窗口，如果是游戏窗口则生效
	POINT mousePos;
	GetCursorPos(&mousePos);
	auto wnd = ::WindowFromPoint(mousePos);
	//wnd->m_hWnd
	if (!wnd || wnd != m_gameWnd)
	{
		return;
	}
	auto uiroot = CRDWnd2DManager::Get()->GetUIManager_DeskTop();
	if (!uiroot)
	{
		return;
	}
	std::wstring uiname;
	std::wstring parentName;
	POINT  rpos = { 0,0 };
	RECT re = { 0, 0, 0, 0 };
	RECT re2 = { 0, 0, 0, 0 };
	::GetWindowRect(m_gameWnd, &re);
	::GetClientRect(m_gameWnd, &re2);
	re.top = re.bottom - re2.bottom;
	re.left = re.right - re2.right;
	re2 = { 0,0,0,0 };
	CRDWnd2DManager::Get()->ShowAllUi(0,{0,0},"", uiroot, [&](DWORD parent, const char* pname, DWORD address, char* name, POINT pos, POINT rePos, SIZE s) {
		//m_tree1.InsertItem();
		char buf[MAX_PATH] = "";
		sprintf_s(buf, "%X__\"%s\"  [%d,%d][] size=[%d,%d]\n", address, name, pos.x, pos.y, s.cx, s.cy);
		OutputDebugStringA(buf);
		if (s.cx > 0 && s.cy > 0)
		{
			RECT  tre = { re.left + pos.x, re.top + pos.y, re.left + pos.x + s.cx ,re.top + pos.y + s.cy };
			if (PtInRect(&tre, mousePos))
			{
				uiname = string2wstring(name);
				parentName = string2wstring(pname);
				rpos = rePos;
				re2 = tre;
			}
		}
		//添加到ROOT


		});

	showRectInDesktop(re2);
	m_uiname_edit.SetWindowTextW(uiname.c_str());
	m_parentName_edit.SetWindowTextW(parentName.c_str());
	std::wstring strPos = std::to_wstring(rpos.x) + L"," + std::to_wstring(rpos.y);
	m_pos_edit.SetWindowTextW(strPos.c_str());
}


void CScanUi::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	ReleaseCapture();
	CDialogEx::OnLButtonUp(nFlags, point);

}


void CScanUi::OnNMDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	HTREEITEM parentitem = NULL;
	std::wstring uiname;
	std::wstring parentName;
	POINT  pos = { 0,0 };
	auto select = m_tree1.GetSelectedItem();
	for (auto item : m_treedata) {
		if (select == item.treeItem)
		{
			uiname = item.name;
			pos = item.pos;
			if (item.parent != 0)
			{
				auto parent = item.parent;
				//找到此节点的父，父，父
				for (auto ii : m_treedata) {
					if (ii.uiaddress == parent)
					{
						parentName = ii.name;
						break;
					}

				}
			}
			break;
		}
	}
	m_uiname_edit.SetWindowTextW(uiname.c_str());
	m_parentName_edit.SetWindowTextW(parentName.c_str());
	std::wstring strPos = std::to_wstring(pos.x) + L"," + std::to_wstring(pos.y);
	m_pos_edit.SetWindowTextW(strPos.c_str());
}
